<?php
/*

 */
class VCode 
{
	private $vcode=null;
	private $img=null;
	private $width=80;
	private $height=32;
	private $count=4;
	private $bgimg=null;
	private $type="gif";
	private $str=2;
	private $fontfiles=array("./elephant.ttf");
	private $code="0123456789qwertyuipasdfghjkzxcvbnmQWERTYUIPASDFGHJKLZXCVBNM";
	private $pmarr=array("width","height","count","bgimg","type","str","fontfiles","point","arc");
	private $rgb=array();
	private $point=30;
	private $arc=500;


	function __construct($arr=null)
	{
		$this->setpm($arr);
	}
	
	function getCode()
	{
		$this->makeCode();
		return $this->vcode;
	}

	
	function getImg()
	{
		$this->randColor();
		$this->createImg();
		$this->createObstruct2();
		$this->createCode();
		$this->createObstruct1();
		$this->outputImg();
	}
	

	
	private function setpm($arr)
	{
		if(empty($arr))
		{
			return false;
		}
		foreach ($arr as $key=>$val)
		{
			$key=strtolower($key);
			if(in_array($key,$this->pmarr))
			{
				$this->$key=$val;
			}
		}
	}

	
	private function createImg()
	{
		$bgimg=null;
		$this->img=imagecreatetruecolor($this->width, $this->height);
		$s=$this->rgb[0];
		$e=$this->rgb[1];
		$bgcolor=imagecolorallocate($this->img,rand($s,$e),rand($s,$e),rand($s,$e));
		imagefill($this->img, 0, 0, $bgcolor);
	
		if($this->bgimg)
		{
			$bgimgname=$this->bgimg;
			$arr=getimagesize($bgimgname);
			$width=$arr[0];
			$height=$arr[1];
			$str=$arr[2];
			switch ($str)
			{
				case 1:$bgimg=imagecreatefromgif($bgimgname);break;
				case 2:$bgimg=imagecreatefromjpeg($bgimgname);break;
				case 3:$bgimg=imagecreatefrompng($bgimgname);break;
			}
			imagecopy($this->img,$bgimg,0,0,0,0,$this->width,$this->height);
			imagedestroy($bgimg);
		}
	}


	private function createObstruct1()
	{
		$a=$this->width*$this->height/$this->point;
		for($i=0;$i<$a;$i++)
		{
			$color1=imagecolorclosest($this->img, rand(0,255), rand(0,255), rand(0,255));
			imagesetpixel($this->img, rand(0,$this->width), rand(0,$this->height), $color1);
		}
	}
	
	
	private function createObstruct2()
	{
		$b=round($this->width*$this->height/500);
		for($i=0;$i<$b;$i++)
		{
			$color2=imagecolorclosest($this->img, rand(0,255), rand(0,255), rand(0,255));
			imagearc($this->img, rand(0,$this->width),rand(0,$this->height), rand(0,$this->width),rand(0,$this->height), rand(0,360), rand(0,360), $color2);
		}
	}

	
	private function createCode()
	{
		
		$mins=round($this->height*0.4);
		$maxs=round($this->height*0.6);
		$fontsize=array();
		$fontfiles=array();
		$fontrotate=array();
		$fontwidth=array();
		$fontheight=array();
		$sum=0;
		
		for($i=0;$i<strlen($this->vcode);$i++)
		{
			$fontsize[$i]=round(rand($mins,$maxs));
			if(!empty($this->fontfiles))
			{
				$index=round(rand(0,count($this->fontfiles)-1));
				$fontfiles[$i]=$this->fontfiles[$index];
				$fontrotate[$i]=round(rand(-20,20));
				$info=imagettfbbox($fontsize[$i],$fontrotate[$i],$fontfiles[$i],$this->vcode{$i});
				$fontwidth[$i]=max($info[2]-$info[0],$info[4]-$info[6]);
				$fontheight[$i]=max($info[1]-$info[7],$info[3]-$info[5]);
				$sum+=$fontwidth[$i];
			}
			else
			{
				$fontheight[$i]=$fontsize[$i];
				$fontwidth[$i]=$fontsize[$i];
				$sum+=$fontsize[$i];
			}
		}
		$s=$this->rgb[2];
		$e=$this->rgb[3];
		$baseX=0;
		$diff=0;
		$fg=0;
		if(!empty($this->fontfiles))
		{
			$diff=$this->width-$sum-($fontwidth[0]*0.2*2);
			if($diff>0)
			{
				$fg=$diff/(strlen($this->vcode)+1);
			}
			$baseX=$fontwidth[0]*0.2+$fg;
		}
		else 
		{
			$diff=$this->width-$sum;
			if($diff>0)
			{
				$fg=$diff/(strlen($this->vcode)+1);
			}
		}
		for($i=0;$i<strlen($this->vcode);$i++)
		{
			$color=imagecolorallocate($this->img,rand($s,$e),rand($s,$e),rand($s,$e));
			
			if(!empty($this->fontfiles))
			{
				$y=($this->height-$fontheight[$i])/2+$fontheight[$i];
				imagettftext($this->img,$fontsize[$i], $fontrotate[$i],$baseX,$y, $color,$fontfiles[$i],$this->vcode{$i});
			}
			else
			{
				$y=($this->height-$fontsize[$i])/2;
				imagechar($this->img,$fontsize[$i], $baseX,$y, $this->vcode{$i}, $color);
			}
			$baseX+=$fontwidth[$i]+$fg;
		}
	}

	
	private function makeCode()
	{
		switch ($this->str)
		{
			case 0:$s=0;$e=9;break;
			case 1:$s=10;$e=58;break;
			case 2:$s=0;$e=58;break;
		}
		for($i=0;$i<$this->count;$i++)
		{
			$this->vcode.=$this->code[rand($s, $e)];
		}
	}


	private function randColor()
	{
		$m=rand(0,1);
		if($m==0)
		{
			$this->rgb[0]=0;
			$this->rgb[1]=100;
			$this->rgb[2]=200;
			$this->rgb[3]=255;
		}
		else
		{
			$this->rgb[0]=200;
			$this->rgb[1]=255;
			$this->rgb[2]=0;
			$this->rgb[3]=100;
		}
	}

	
	private function outputImg()
	{
		$t=strtolower($this->type);
		ob_clean();
		switch ($t)
		{
			case "gif":
				header("Content-Type:image/gif");
				imagegif($this->img);
				break;
			case "jpg" || "jpeg":
				header("Content-Type:image/jpeg");
				imagejpeg($this->img);
				break;
			case "png":
				header("Content-Type:image/png");
				imagepng($this->img);
				break;
		}
		imagedestroy($this->img);
	}


}